'use strict';
var crypto = require('../utils/crypto');
var express = require('express');
var bodyParser = require('body-parser');
var db = require('../utils/db');
var http = require('../utils/http');
var room_service = require("./room_service");
var user_mgr = require("./usermgr");
var async = require("async");
var cache = require('../utils/redis');
var xinchentianPay = require("./pay/xinchentian");
var USER_POSITION_EXPIRE = require(process.argv[2]).USER_POSITION_EXPIRE;
var app = express();
var config = null;

var log4js = require('log4js');
var log = log4js.getLogger("hallServer");


function check_account(req, res) {
	var account = req.query.account;
	var sign = req.query.sign;
	if (account == null || sign == null) {
		http.send(res, 1, "unknown error");
		return false;
	}
	/*
	var serverSign = crypto.md5(account + req.ip + config.ACCOUNT_PRI_KEY);
	if(serverSign != sign){
		http.send(res,2,"login failed.");
		return false;
	}
	*/
	return true;
}


app.use(log4js.connectLogger(log4js.getLogger("httpAccess"), { level: 'auto' }));

//设置跨域访问
app.all('*', function (req, res, next) {
	res.header("Access-Control-Allow-Origin", "*");
	res.header("Access-Control-Allow-Headers", "X-Requested-With");
	res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
	res.header("X-Powered-By", ' 3.2.1');
	res.header("Content-Type", "application/json;charset=utf-8");
	next();
});

app.get('/testNet', function (req, res) {
	http.send(res, 0, "ok");
});
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
app.use(bodyParser.json());

app.get('/login', function (req, res) {
	if (!check_account(req, res)) {
		log.warn("login fail for account doesn't exist!");
		return;
	}

	var ip = req.ip;
	if (ip.indexOf("::ffff:") != -1) {
		ip = ip.substr(7);
	}

	//查询玩家信息
	var account = req.query.account;
	db.get_user_data(account, function (userinfo) {
		if (userinfo == null) {
			log.warn("login fail for user info doesn't exist!");
			http.send(res, 0, "ok");
			return;
		}
		log.debug("login user id == " + userinfo.userid + "room id == " + userinfo.roomid);

		var ret = {
			account: userinfo.account,
			userid: userinfo.userid,
			name: userinfo.name,
			lv: userinfo.lv,
			exp: userinfo.exp,
			coins: userinfo.coins,
			gems: userinfo.gems,
			ip: userinfo.regIp,
			sex: userinfo.sex,
			headimg: userinfo.headimg,
		};

		//如果用户处于房间中，则需要对其房间进行检查。 如果房间还在，则通知用户进入
		var roomId = userinfo.roomid;
		if (roomId != null) {
			//检查房间是否存在
			db.is_room_exist(roomId, function (retval) {
				if (retval) {
					room_service.enterRoom(userinfo.userid, userinfo.name, roomId, function (errcode, enterInfo) {
						console.log(enterInfo);
						if (enterInfo != null) {
							ret.room = {
								roomid: roomId,
								ip: enterInfo.ip,
								port: enterInfo.port,
								token: enterInfo.token,
								time: Date.now()
							};
							ret.room.sign = crypto.md5(ret.room.roomid + ret.room.token + ret.room.time + config.ROOM_PRI_KEY);

							async.series({
								one: function (callback) {
									db.updateOnlineStatus(userinfo.userid, 1);
									callback(null, 1);
								},
								two: function (callback) {
									db.recordLoginLog(userinfo.userid);
									callback(null, 2);
								},
								three: function (callback) {
									http.send(res, 0, "ok", ret);
								}
							}, function (err, results) {
								log.debug(results);
							});

							log.debug("enter room success!");
						}
						else {
							//如果房间不在了，表示信息不同步，清除掉用户记录
							db.set_room_id_of_user(userinfo.userid, null);
							log.warn("warning: enter room failed for room info is not new in memory!");
						}
					});
				}
				else {
					//如果房间不在了，表示信息不同步，清除掉用户记录
					db.set_room_id_of_user(userinfo.userid, null);
					http.send(res, 0, "ok", ret);
					log.warn("warning: room info is null in memory, user's room id is setted to null!");
				}
			});
		} else {
			user_mgr.storeNewUser(userinfo);
			http.send(res, 0, "ok", ret);
			log.warn("warning: room id is null in memory!");
		}
	});
});

app.get('/getGems', function (req, res) {
	var account = req.query.account;
	if (account === undefined) {
		return;
	}
	db.get_gems(account, function (ret) {
		if (ret == null) {
			log.warn("get gems failed!");
			http.send(res, -1, "get gems failed!");
		}
		else {
			log.debug("get gems success!");
			http.send(res, 0, "ok", { data: ret });
		}
	});
});

app.get('/create_user', function (req, res) {
	if (!check_account(req, res)) {
		return;
	}
	var account = req.query.account;
	var name = req.query.name;
	var coins = 1000;
	var gems = 18;
	var userId = user_mgr.getUserIdByAccount(account);
	if (0 == userId) {
		db.get_max_userid(function (data) {
			var userid = 105000;
			if (data != null) {
				++data.userid;
				userid = (data.userid >= 105000) ? data.userid : userid;
			}
			db.create_user(userid, account, name, coins, gems, 0, null, '0.0.0.0', function (ret1, ret2) {
				if (ret2 == false) {
					http.send(res, 2, "system error.");
				}
				else {
					http.send(res, 0, "ok");
					var userinfo = {
						userid: userid,
						account: account,
						name: name,
						sex: 0,
						headimg: null,
						lv: 1,
						exp: 0,
						coins: coins,
						gems: gems,
						roomid: null,
						online: 0,
						create_time: Date.now()
					}
					user_mgr.storeNewUser(userinfo);
				}
			});
		});
	}
	else {
		http.send(res, 1, "account have already exist.");
	}
});

app.get('/create_private_room', function (req, res) {
	//验证参数合法性
	var data = req.query;

	//验证玩家身份
	if (!check_account(req, res)) {
		return;
	}

	//获取玩家信息
	var account = data.account;
	var userinfo = user_mgr.getUserInfoByAccount(account);
	if (userinfo == null) {
		http.send(res, -1, "system error");
		return;
	}
	log.debug("create_private_room user id == " + userinfo.userid);

	//置初始值
	data.account = null;
	data.sign = null;
	var conf = data.conf;
	var userId = userinfo.userid;
	var name = userinfo.name;

	log.debug("room config = ", conf);

	//验证玩家状态
	db.get_room_id_of_user(userId, function (roomId) {
		if (roomId != null) {
			db.is_room_exist(roomId, function (ret) {
				if (!ret) {
					db.set_room_id_of_user(userId, null);
					log.warn("room is not exist user id , room id = ", userId, roomId);
					createRoom(res, roomId, account, name, userId, conf);
				} else {
					http.send(res, -1, "user is playing in room now.");
					log.warn("user is playing in room now");
					return;
				}
			});
		} else {
			log.debug("create room user id = ", userId);
			createRoom(res, roomId, account, name, userId, conf);
		}
	});
});

function createRoom(res, roomId, account, name, userId, conf) {
	//创建房间
	room_service.createRoom(account, userId, conf, function (err, roomId) {
		log.debug("create room call back");
		if (err == 0) {
			room_service.enterRoom(userId, name, roomId, function (errcode, enterInfo) {
				if (enterInfo) {
					var ret = {
						roomid: roomId,
						ip: enterInfo.ip,
						port: enterInfo.port,
						token: enterInfo.token,
						time: Date.now()
					};
					ret.sign = crypto.md5(ret.roomid + ret.token + ret.time + config.ROOM_PRI_KEY);
					http.send(res, 0, "ok", ret);
					log.debug("create private room success! ", roomId, enterInfo.token);
				}
				else {
					log.warn("room doesn't exist! ", errcode);
					http.send(res, errcode, "room doesn't exist.");
				}
			});
		}
		else {
			log.warn("create room failed! errcode = ", err);
			http.send(res, err, "create failed.");
		}
	});
}

app.get('/enter_private_room', function (req, res) {
	var data = req.query;
	var roomId = data.roomid;
	if (roomId == null) {
		http.send(res, -1, "parameters don't match api requirements.");
		return;
	}

	if (!check_account(req, res)) {
		return;
	}

	var account = data.account;
	var userInfo = user_mgr.getUserInfoByAccount(account);
	if (userInfo == null) {
		http.send(res, -1, "system error");
		return;
	}
	log.debug("enter_private_room user id == " + userInfo.userid);

	//进入房间
	room_service.enterRoom(userInfo.userid, userInfo.name, roomId, function (errcode, enterInfo) {
		if (enterInfo) {
			var ret = {
				roomid: roomId,
				ip: enterInfo.ip,
				port: enterInfo.port,
				token: enterInfo.token,
				time: Date.now()
			};
			ret.sign = crypto.md5(roomId + ret.token + ret.time + config.ROOM_PRI_KEY);
			http.send(res, 0, "ok", ret);
		}
		else {
			http.send(res, errcode, "enter room failed.");
		}
	});
});

app.get('/get_history_list', function (req, res) {
	var data = req.query;
	if (!check_account(req, res)) {
		return;
	}
	var account = data.account;
	var userid = user_mgr.getUserIdByAccount(account);
	if (userid != null) {
		db.get_user_history(userid, function (data) {
			http.send(res, 0, "ok", { history: data });
		});
	}
});


app.get('/get_rooms_history', function (req, res) {
	var data = req.query;
	if (!check_account(req, res)) {
		return;
	}
	var roomId = data.roomId;
	var account = data.account;
	var userid = user_mgr.getUserIdByAccount(account);
	if (userid != null && roomId != null) {
		db.get_rooms_history([{ room_id: roomId }], function (data) {
			http.send(res, 0, "ok", { history: data });
		});
	}
});


app.get('/get_games_of_room', function (req, res) {
	var data = req.query;
	var uuid = data.uuid;
	if (uuid == null) {
		http.send(res, -1, "parameters don't match api requirements.");
		return;
	}
	if (!check_account(req, res)) {
		return;
	}
	db.get_games_of_room(uuid, function (data) {
		console.log(data);
		http.send(res, 0, "ok", { data: data });
	});
});

app.get('/get_detail_of_game', function (req, res) {
	var data = req.query;
	var uuid = data.uuid;
	var index = data.index;
	if (uuid == null || index == null) {
		http.send(res, -1, "parameters don't match api requirements.");
		return;
	}
	if (!check_account(req, res)) {
		return;
	}
	db.get_detail_of_game(uuid, index, function (data) {
		http.send(res, 0, "ok", { data: data });
	});
});

app.get('/get_user_status', function (req, res) {
	if (!check_account(req, res)) {
		return;
	}
	var account = req.query.account;
	db.get_gems_and_coins(account, function (data) {
		if (data != null) {
			http.send(res, 0, "ok", { gems: data.gems, coins: data.coins });
		}
		else {
			http.send(res, 1, "get coins and gems failed.");
		}
	});
});

app.get('/update_online_status', function (req, res) {
	var userid = req.query.userid;
	var status = req.query.status;
	db.updateOnlineStatus(userid, status, function (ret) {
		if (ret)
			http.send(res, 0, "ok");
		else
			http.send(res, 1, "update user online status failed!");
	});
});

app.get('/get_message', function (req, res) {
	if (!check_account(req, res)) {
		return;
	}
	var type = req.query.type;

	if (type == null) {
		http.send(res, -1, "parameters don't match api requirements.");
		return;
	}

	var version = req.query.version;
	db.get_message(type, version, function (data) {
		if (data != null) {
			http.send(res, 0, "ok", { msg: data.msg, version: data.version });
		}
		else {
			http.send(res, 1, "get message failed.");
		}
	});
});


// 上传用户位置
app.get('/upload_user_position', function (req, res) {
	var account = req.query.account;
	var sign = req.query.sign;
	if (account == null || sign == null) {
		return http.send(res, 1, "unknown error");
	}

	//  经度，纬度
	var lat = req.query.lat;
	var lng = req.query.lng;
	console.log(req.query, lat, lng);
	var userId = user_mgr.getUserIdByAccount(account);
	if (lat == null || lng == null || userId === 0) {
		http.send(res, -1, "parameters don't match api requirements.");
		return;
	}

	if (lat <= 0 || lat > 90 || lng <= 0 || lat > 180) {
		return http.send(res, -1, "parameters lat or lng is error.");
	}

	var cacheUserInfo = {
		userId: userId,
		lat: lat,
		lng: lng
	};
	var positionKey = 'position_' + userId;
	cache.setStrCache(positionKey, cacheUserInfo, USER_POSITION_EXPIRE, function () {
		http.send(res, 0, "ok");
	});
});

app.get('/get_befor_inpay_gems', function (req, res) {
	// console.log(req.query.sdcustomno, req.query.userId);
	if (!(req.query.sdcustomno && req.query.userId)) {
		return http.send(res, -1, "parameters error.");
	}
	xinchentianPay.checkAndSetUserPayStautsAndReturnGems(req.query.sdcustomno, req.query.userId, res);
});


app.get('/pay_callback', function (req, res) {
	xinchentianPay.payCallback(req.query, res);
});


app.get('/create_pay_order', function (req, res) {
	if (!req.query.userId) {
		return http.send(res, -1, "parameters error.");
	}
	xinchentianPay.createPayOrder(req.query, res);
});


app.get('/get_pay_config', function (req, res) {
	var account = req.query.account;
	var sign = req.query.sign;
	if (account == null || sign == null) {
		return http.send(res, 1, "unknown error");
	}
	db.get_pay_config()
		.then(function (ret) {
			var info = {
				config: ret,
				hintMsg: '获取免费钻石、申请代理、代理充值咨询客服微信号jiudukefu01'
			}
			return http.send(res, 0, info);
		}).catch(function (err) {
			return http.send(res, -1, {});
		});
});

//分享
app.get('/share', function (req, res) {
	console.log("receive share command! user id == " + req.query.userId);
	var userId = req.query.userId;
	if (userId === undefined) {
		console.log("guo: can't find user game data.");
		return;
	}
	// 更新每天分享钻石
	db.updateUserSharedGiveDiamonds(userId, 3, function (status) {
		if (!status) {
			log.warn("share diamond failed!");
			http.send(res, -1, "share diamond failed!");
		}
		else {
			log.debug("share diamond success!");
			http.send(res, 0, "ok");
		}
	});
});

//获取活动数据
app.get('/activity', function (req, res) {
	db.get_activity_data(function (ret) {
		var data = [];
		if (ret != null) {

			for (let i = 0; i < ret.length; ++i) {
				data.push({
					name: ret[i].name,
					title: ret[i].title,
					comment: ret[i].comment
				})
			}
			//console.log(data);
		}
		http.send(res, 0, "ok", { data: data });
	});
});

//获取活动数据
app.get('/get_room_cost_config', function (req, res) {
	db.getAllCostConfig(function (ret) {
		var data = {};
		if (ret != null) {
			for (let i = 0; i < ret.length; ++i) {
				if (data[ret[i].room_type] === undefined) {
					data[ret[i].room_type] = [];
				}
				data[ret[i].room_type].push({
					roomType: ret[i].room_type,
					roundNo: ret[i].round_no,
					costDiamond: ret[i].cost_diamond
				})
			}
			//console.log(data);
		}
		http.send(res, 0, "ok", { data: data });
	});
});

exports.start = function ($config) {
	config = $config;
	app.listen(config.CLEINT_PORT);
	log.info("client service is listening on port " + config.CLEINT_PORT);

	user_mgr.initUserInfo();
	setInterval(user_mgr.update, 5000);
};